package sg.edu.ntu.bloch.tictactoe.view;

import java.io.InputStream;
import java.util.HashMap;
import java.util.InvalidPropertiesFormatException;
import java.util.Map;
import java.util.Properties;

import org.apache.log4j.Logger;


public class ViewFactory {
	Logger _log = Logger.getLogger(ViewFactory.class);
	private final Viewable viewInstance;
	private static ViewFactory viewFactory;

	public static enum ViewType {
		CONSOLE {
			Viewable getViewInstance() throws Exception {
				return new ConsoleView();
			}
		},
		SWING {
			Viewable getViewInstance() throws Exception{
				throw new UnsupportedOperationException("no supported yet");
			}
		};
		private static Map<String, ViewType> map;
		static {
			map = new HashMap<String, ViewType>();
			for (ViewType type : ViewType.values()) {
				map.put(type.toString(), type);
			}
		}

		public static ViewType fromString(String label) {
			return map.get(label.trim().toUpperCase());
		}

		abstract Viewable getViewInstance() throws Exception;
	}

	private ViewFactory() throws Exception {
		try {
			InputStream is = ClassLoader
					.getSystemResourceAsStream("tictactoe.properties");
			Properties prop = new Properties();
			prop.load(is);
			ViewType viewType = ViewType.fromString(prop
					.getProperty("view.type"));
			if (viewType == null) {
				throw new InvalidPropertiesFormatException(
						"Invalid View Type, please check"
								+ " tictactoe properties files");
			}
			_log.debug("View type is "+ viewType);
			viewInstance = viewType.getViewInstance();
		} catch (InvalidPropertiesFormatException e) {
			_log.error(e.getMessage());
			throw new Exception("Invalid view from properties");
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}
	public Viewable getView(){
		return viewInstance;
	}

	public static synchronized ViewFactory getInstance() throws Exception {
		if (viewFactory == null) {
			viewFactory = new ViewFactory();
		}
		return viewFactory;
	}

}
